package com.dog.basics.service.common.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dog.basics.bean.dto.admin.common.ArticleAddDto;
import com.dog.basics.bean.dto.admin.common.ArticleEditDto;
import com.dog.basics.bean.dto.admin.common.ArticleFormDto;
import com.dog.basics.bean.model.common.DogComArticle;
import com.dog.basics.bean.model.common.DogComArticleClass;
import com.dog.basics.bean.model.common.DogComArticleComment;
import com.dog.basics.bean.model.common.DogComArticleUser;
import com.dog.basics.bean.vo.admin.common.PcArticleVo;
import com.dog.basics.bean.vo.api.common.ApiArticleVo;
import com.dog.basics.common.util.Json;
import com.dog.basics.common.util.PageParam;
import com.dog.basics.dao.common.DogComArticleClassMapper;
import com.dog.basics.dao.common.DogComArticleCommentMapper;
import com.dog.basics.dao.common.DogComArticleMapper;
import com.dog.basics.dao.common.DogComArticleUserMapper;
import com.dog.basics.security.util.SecurityUtils;
import com.dog.basics.service.common.IDogComArticleService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * CMS文章表 服务实现类
 * </p>
 *
 * @author guonh
 * @since 2020-05-20
 */
@Service
@AllArgsConstructor
public class DogComArticleServiceImpl extends ServiceImpl<DogComArticleMapper, DogComArticle> implements IDogComArticleService {
    private final DogComArticleCommentMapper dogComArticleCommentMapper;
    private final DogComArticleClassMapper dogComArticleClassMapper;
    private final DogComArticleUserMapper articleUserMapper;

    /**
     * @Description: 增加CMS文章
     * @Param:
     * @return: Boolean
     * @Author: zhangrm
     * @Date: 2020/05/22  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveObj(ArticleAddDto obj) {
        DogComArticle dogComArticle = new DogComArticle();
        BeanUtil.copyProperties(obj, dogComArticle);
        if (CollUtil.isNotEmpty(obj.getAttachmentPathList())) {
            dogComArticle.setAttachmentPath(Json.toJsonString(obj.getAttachmentPathList()));
        }
        if (CollUtil.isNotEmpty(obj.getArticleIdArrayList())) {
            dogComArticle.setArticleIdArray(Json.toJsonString(obj.getArticleIdArrayList()));
        }

        Validator.validateTrue(obj.getStatus().equals(0) || obj.getStatus().equals(1), "文章状态有误！");
        dogComArticle.setCreateTime(DateUtil.currentSeconds());
        dogComArticle.setCreateBy(SecurityUtils.getSysUser().getUserId());
        Validator.validateTrue(this.save(dogComArticle), "增加cms文章失败!");
        return Boolean.TRUE;
    }

    /**
     * @Description: 删除CMS文章
     * @Param: ids
     * @return: Boolean
     * @Author: zhangrm
     * @Date: 2020/05/22  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteObj(Long id) {
        DogComArticle dogComArticle = this.getById(id);
        Validator.validateNotNull(dogComArticle, "无此数据");
        //删除文章下的评论
        dogComArticleCommentMapper.delete(Wrappers.<DogComArticleComment>lambdaQuery().eq(ObjectUtil.isNotEmpty(dogComArticle.getId()), DogComArticleComment::getArticleId, dogComArticle.getId()));
        return this.removeById(id);
    }

    /**
     * @Description: 修改CMS文章
     * @Param:
     * @return: Boolean
     * @Author: zhangrm
     * @Date: 2020/05/22  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editObj(ArticleEditDto obj) {
        DogComArticle dogComArticle = this.getById(obj.getId());
        Validator.validateNotNull(dogComArticle, "无此数据");
        Validator.validateTrue(!dogComArticle.getStatus().equals(2), "已发布文章不能修改！");
        Validator.validateTrue(!obj.getStatus().equals(2), "不能修改未已发布！");
        BeanUtil.copyProperties(obj, dogComArticle);
        if (CollUtil.isNotEmpty(obj.getAttachmentPathList())) {
            dogComArticle.setAttachmentPath(Json.toJsonString(obj.getAttachmentPathList()));
        }
        if (CollUtil.isNotEmpty(obj.getArticleIdArrayList())) {
            dogComArticle.setArticleIdArray(Json.toJsonString(obj.getArticleIdArrayList()));
        }
        dogComArticle.setUpdateTime(DateUtil.currentSeconds());
        dogComArticle.setUpdateBy(SecurityUtils.getSysUser().getUserId());
        return this.updateById(dogComArticle);
    }


    /**
     * @Description: 分页CMS文章列表
     * @Param:
     * @return:
     * @Author: zhangmr
     * @Date:
     */
    @Override
    public IPage<PcArticleVo> getPageList(PageParam page, ArticleFormDto obj) {
        IPage iPage = this.page(page, Wrappers.<DogComArticle>lambdaQuery()
                .eq(ObjectUtil.isNotNull(obj.getId()), DogComArticle::getId, obj.getId())
                .eq(ObjectUtil.isNotNull(obj.getClassId()), DogComArticle::getClassId, obj.getClassId())
                .eq(ObjectUtil.isNotNull(obj.getCommendFlag()), DogComArticle::getCommendFlag, obj.getCommendFlag())
                .eq(ObjectUtil.isNotNull(obj.getCommentFlag()), DogComArticle::getCommentFlag, obj.getCommentFlag())
                .eq(ObjectUtil.isNotNull(obj.getStatus()), DogComArticle::getStatus, obj.getStatus())
                .eq(ObjectUtil.isNotNull(obj.getCreateBy()), DogComArticle::getCreateBy, obj.getCreateBy())
                .eq(ObjectUtil.isNotNull(obj.getUserId()), DogComArticle::getUserId, obj.getUserId())
                .like(StrUtil.isNotBlank(obj.getTitle()), DogComArticle::getTitle, obj.getTitle())
                .like(StrUtil.isNotBlank(obj.getAuthor()), DogComArticle::getAuthor, obj.getAuthor())
                .like(StrUtil.isNotBlank(obj.getKeyword()), DogComArticle::getKeyword, obj.getKeyword())
                .in(StrUtil.isNotBlank(obj.getTag()), DogComArticle::getTag, obj.getTag())
                .like(StrUtil.isNotBlank(obj.getPublisherName()), DogComArticle::getPublisherName, obj.getPublisherName())
                .ge(ObjectUtil.isNotEmpty(obj.getPublicTimeStart()), DogComArticle::getPublicTime, obj.getPublicTimeStart())
                .le(ObjectUtil.isNotEmpty(obj.getPublicTimeEnd()), DogComArticle::getPublicTime, obj.getPublicTimeEnd())
                .ge(ObjectUtil.isNotEmpty(obj.getCreateTimeStart()), DogComArticle::getCreateTime, obj.getCreateTimeStart())
                .le(ObjectUtil.isNotEmpty(obj.getCreateTimeEnd()), DogComArticle::getCreateTime, obj.getCreateTimeEnd())
                .orderBy(Boolean.TRUE, obj.getIsOrderByAvg(), DogComArticle::getCreateTime));
        List<DogComArticle> records = iPage.getRecords();
        iPage.setRecords(records.stream().map(e -> {
            PcArticleVo pcArticleVo = new PcArticleVo();
            BeanUtil.copyProperties(e, pcArticleVo);
            if (Validator.isNotEmpty(e.getAttachmentPath())) {
                pcArticleVo.setAttachmentPathList(Json.parseArray(e.getAttachmentPath(), String[].class));
            }
            if (Validator.isNotEmpty(e.getArticleIdArray())) {
                pcArticleVo.setArticleIdArrayList(Json.parseArray(e.getArticleIdArray(), String[].class));
            }
            DogComArticleClass dogComArticleClass = dogComArticleClassMapper.selectById(e.getClassId());
            pcArticleVo.setClassName(ObjectUtil.isNotNull(dogComArticleClass) ? dogComArticleClass.getName() : "");
            return pcArticleVo;
        }).collect(Collectors.toList()));
        return iPage;
    }


    /**
     * @Description: 分页cms文章列表API
     * @Param:
     * @return:
     * @Author: zhangmr
     * @Date:
     */
    @Override
    public IPage<ApiArticleVo> getPageListApi(PageParam page, com.dog.basics.bean.dto.api.common.ArticleFormDto obj) {
        IPage iPage = this.page(page, Wrappers.<DogComArticle>lambdaQuery()
                .eq(ObjectUtil.isNotNull(obj.getId()), DogComArticle::getId, obj.getId())
                .eq(ObjectUtil.isNotNull(obj.getClassId()), DogComArticle::getClassId, obj.getClassId())
                .eq(ObjectUtil.isNotNull(obj.getCommendFlag()), DogComArticle::getCommendFlag, obj.getCommendFlag())
                .eq(ObjectUtil.isNotNull(obj.getCommentFlag()), DogComArticle::getCommentFlag, obj.getCommentFlag())
                .eq(DogComArticle::getStatus, 2)
                .like(StrUtil.isNotBlank(obj.getTitle()), DogComArticle::getTitle, obj.getTitle())
                .like(StrUtil.isNotBlank(obj.getAuthor()), DogComArticle::getAuthor, obj.getAuthor())
                .like(StrUtil.isNotBlank(obj.getKeyword()), DogComArticle::getKeyword, obj.getKeyword())
                .like(StrUtil.isNotBlank(obj.getTag()), DogComArticle::getTag, obj.getTag())
                .ge(ObjectUtil.isNotEmpty(obj.getPublicTimeStart()), DogComArticle::getPublicTime, obj.getPublicTimeStart())
                .le(ObjectUtil.isNotEmpty(obj.getPublicTimeEnd()), DogComArticle::getPublicTime, obj.getPublicTimeEnd())
                .orderBy(Boolean.TRUE, obj.getIsOrderByAvg(), DogComArticle::getCreateTime));
        List<DogComArticle> records = iPage.getRecords();
        iPage.setRecords(records.stream().map(e -> {
            ApiArticleVo apiArticleVo = new ApiArticleVo();
            BeanUtil.copyProperties(e, apiArticleVo);
            if (Validator.isNotEmpty(e.getAttachmentPath())) {
                apiArticleVo.setAttachmentPathList(Json.parseArray(e.getAttachmentPath(), String[].class));
            }
            if (Validator.isNotEmpty(e.getArticleIdArray())) {
                apiArticleVo.setArticleIdArrayList(Json.parseArray(e.getArticleIdArray(), String[].class));
            }
            apiArticleVo.setClassName(dogComArticleClassMapper.selectById(e.getClassId()).getName());
            return apiArticleVo;
        }).collect(Collectors.toList()));
        return iPage;
    }

    /**
     * @Description: 增加cms文章点击量或分享数
     * @Param:
     * @return: Boolean
     * @Author: zhangrm
     * @Date: 2020/05/22  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addedit(Integer flag, Long articleId) {
        DogComArticle dogComArticle = this.getById(articleId);
        Integer count = articleUserMapper.selectCount(Wrappers.<DogComArticleUser>lambdaQuery()
                .eq(DogComArticleUser::getAorcId, articleId)
                .eq(DogComArticleUser::getUserId, SecurityUtils.getUser().getUserId())
                .eq(DogComArticleUser::getOperationFlag, flag));
        Validator.validateTrue(count.equals(0), "不能重复增加");

        Validator.validateNotNull(dogComArticle, "无此数据");
        if (Validator.equal(flag, 0)) {
            dogComArticle.setClick(dogComArticle.getClick() + 1);
        } else if (Validator.equal(flag, 1)) {
            dogComArticle.setShareCount(dogComArticle.getShareCount() + 1);
        }
        DogComArticleUser articleUser = new DogComArticleUser();
        articleUser.setAorcId(articleId);
        articleUser.setOperationFlag(flag);
        articleUser.setUserId(SecurityUtils.getUser().getUserId());
        articleUser.setCreateTime(DateUtil.currentSeconds());
        articleUser.setCreateBy(SecurityUtils.getUser().getUserId());
        Validator.validateTrue(retBool(articleUserMapper.insert(articleUser)), "关联信息添加失败");
        return this.updateById(dogComArticle);
    }

    /**
     * @Description CMS文章回收
     * @Author zhangmr
     * @Date 2020/7/20 0020 下午 16:00
     * @Param
     * @Return
     * @Exception
     */
    @Override
    public Boolean back(Long id) {
        DogComArticle comArticle = this.getById(id);
        Validator.validateNotNull(comArticle, "文章不存在！");
        // Validator.validateTrue(!comArticle.getStatus().equals(2), "已发布文章不能回收!");
        comArticle.setStatus(3);
        return this.updateById(comArticle);
    }

    /**
     * @Description CMS文章审核
     * @Author zhangmr
     * @Date 2020/7/20 0020 下午 16:08
     * @Param
     * @Return
     * @Exception
     */
    @Override
    public Boolean examine(Long id, Integer status) {
        DogComArticle comArticle = this.getById(id);
        Validator.validateNotNull(comArticle, "文章不存在！");
        Validator.validateTrue(comArticle.getStatus().equals(1), "待审核文章才能审核!");
        Validator.validateTrue(status.equals(2) || status.equals(4), "待审核文章只能修改已发布或打回");
        comArticle.setStatus(status);
        comArticle.setPublicTime(DateUtil.currentSeconds());
        return this.updateById(comArticle);
    }
}
